/******************************************************************************
 *      Mestrado em Ciência da Computação - UFMS
 *		Redes de Computadores - Prof. Dr. Ronaldo Alves Ferreira
 *		Alunos: Geraldo Landre, Marcel Tolentino, Vinícius Bueno
 *****************************************************************************/
 
#include "multi_server.h"
#include <signal.h>
/* IMPLEMENTAÇÃO DA FUNÇÃO HTTPD */

void multi_httpd(vstring *port,int lg_maintenance)
{
    int sockfd = 0; /* fd do socket do servidor */
    int new_fd = 0; /* fd do socket para tratar requisições do cliente */
    int cont_process = 0;
    pid_t pid; /* uso do fork */
    struct addrinfo *srv = NULL;
    struct sockaddr_in client_name; /*estrutura que irá receber os dados do cliente*/
    struct sigaction sa;
    socklen_t client_name_len = sizeof(client_name); /*tamanho do endereço */
    
    sa.sa_handler = sigchld_handler; // reap all dead processes
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = SA_RESTART;

    if(sigaction(SIGCHLD, &sa, NULL) == -1)
    {
        perror("sigaction");
        exit(1);
    }

    if(lg_maintenance)
        printf("HTTP Server under maintenance started on port %s\n", port->pt);
    else
        printf("HTTP Server Multi-Process started on port %s\n", port->pt);

    /* socket, com reuso de socket */
    sockfd = srv_getboundsockfd(srv,port,1);

    /* iniciar o listen */
    int status = srv_listen(sockfd,BACKLOG);
    if(status < 0)
    {
        perror("listen:");
        exit(1);
    }

    while(1)
    {
        /* efetuar o accept */
        new_fd = accept(sockfd, (struct sockaddr *) &client_name, &client_name_len);

        if(new_fd == -1)
        {
            perror("erro no accept\n");
            exit(1);
        }

        signal(SIGCLD, SIG_IGN); /* ignora o sinal SIGCLD e trata processos zumbis*/
        cont_process++;
        pid = fork();
        if(pid < 0)
            perror("ERROR on fork");

        if(pid == 0) /* Processo filho */
        {
            sock_close(sockfd,"sockfd"); /* fecha o fd do socket servidor (pois não irá precisar) */
            connection_handle(new_fd);
            exit(0);
        }
        else
            sock_close(new_fd,"new_fd");
    }/*fim do while */
    sock_close(sockfd,"sockfd");
}